package uk.ac.cam.djjb2.mygame;

import java.io.DataInput;
import java.io.IOException;
import java.net.InetAddress;

import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.SpriteSheet;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;

public class GameClientState extends BasicGameState {
	
	ClientNetManager netManager;
	ClientReplicaManager replicaManager;
	TileMap map;
	TileSet tileSet;
	SpriteSheet mapSheet;

	public GameClientState() {
		super();
	}
	
	private ClientReplicaFactory createTileSetProxyFactory() {
		return new ClientReplicaFactory() {

			@Override
			public ClientReplica newInstance(
					ClientReplicaManager replicaManager, int id,
					DataInput message) throws ReplicationException {

				try {
					return new ClientTileMapProxy(replicaManager, id, message, map);
				} catch (IOException e) {
					throw new ReplicationException(e);
				}
			}
			
		};
	}
	
	private ClientReplicationFactory createReplicationFactory() {
		return new DefaultClientReplicationFactory() {
			@Override
			public ClientReplicaFactory createReplicaFactory(
					Class<? extends ClientReplica> type)
					throws ReplicationException {

				if (type == ClientTileMapProxy.class) {
					return createTileSetProxyFactory();
				} else {
					return super.createReplicaFactory(type);
				}
			}
		};
	}
	
	@Override
	public void init(GameContainer container, StateBasedGame game)
			throws SlickException {

		try {
			netManager = new ClientNetManager(InetAddress.getLoopbackAddress(), 4231);
			replicaManager = new ClientReplicaManager(netManager, createReplicationFactory());
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		tileSet = new DefaultTileSet();
		
		mapSheet = new SpriteSheet("map.png", 32, 32);
		map = new TileMap(Vector2i.ZERO, mapSheet, tileSet);
	}

	@Override
	public void render(GameContainer container, StateBasedGame game, Graphics g)
			throws SlickException {
		map.render(Vector2i.ZERO, Vector2i.ZERO, map.getSize());
		
		g.drawString(
				Integer.toString(container.getWidth()) + "x"
						+ Integer.toString(container.getHeight()), 10, 25);
	}

	@Override
	public void update(GameContainer container, StateBasedGame game, int delta)
			throws SlickException {
		
		try {
			netManager.processMessages();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (InvalidMessageException e) {
			e.printStackTrace();
		}
	}

	@Override
	public int getID() {
		return 0;
	}


}
